package com.songcha.library_common.ui.view

import android.animation.Animator
import android.animation.Animator.AnimatorListener
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import com.songcha.library_common.R
import com.songcha.library_common.util.AlgorithmUtil
import com.songcha.library_common.util.dp2px


class CustomSwitchButton: View {
    private val SB_WIDTH=60f.dp2px()
    private val SB_HEIGHT=24f.dp2px()
    private var mUnSelectBackGroundColor=Color.parseColor("#f2f2f2")
    private var mSelectBackGroundColor=Color.GREEN
    private var mIsSelect=false//switch state
    private var mIsAnimating=false
    private var mValue=0f
    private val ANIMATION_DURATIONS=500L
    private var mBgPaint=Paint()
    private var mSelectBgPaint=Paint()
    private var mBtnPaint=Paint()
    private var mOnSelectListener:IOnSelectListener?=null

    interface IOnSelectListener{
        fun onSelect(isSelect:Boolean,isFromUser:Boolean)
    }

    companion object{
        val BUTTON_MARGIN=2.dp2px()
    }

    constructor(context: Context) : super(context) {
        initView(context,null)
    }

    constructor(context: Context, attrs: AttributeSet):this(context,attrs,0){

    }

    constructor(context: Context, attrs: AttributeSet, defStyle:Int):this(context,attrs,defStyle,0){

    }

    constructor(context: Context, attrs: AttributeSet, defStyle:Int, defRes:Int):super(context,attrs,defStyle,defRes){
        initView(context,attrs)
    }

    private fun initView(context: Context, attrs: AttributeSet?){
        isClickable=true

        if(attrs!=null){
            val ta=context.obtainStyledAttributes(attrs, R.styleable.CustomSwitchButton)
            mUnSelectBackGroundColor=ta.getColor(R.styleable.CustomSwitchButton_sb_unselect_background,Color.GRAY)
            mSelectBackGroundColor=ta.getColor(R.styleable.CustomSwitchButton_sb_select_background,Color.GREEN)
            ta.recycle()
        }


        mBgPaint.style=Paint.Style.FILL
        mBgPaint.color=mUnSelectBackGroundColor

        mSelectBgPaint.style=Paint.Style.FILL
        mSelectBgPaint.color=mSelectBackGroundColor

        mBtnPaint.style=Paint.Style.FILL
        mBtnPaint.color=Color.WHITE

    }

    fun setOnSelectListener(listener: IOnSelectListener){
        mOnSelectListener=listener
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(SB_WIDTH.toInt(),SB_HEIGHT.toInt())
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if(event.action==MotionEvent.ACTION_UP){
            if(mIsAnimating) return false
            startAnimation(true)
            return true
        }

        return super.onTouchEvent(event)
    }

    fun setSelect(select:Boolean){
        if(select==mIsSelect) return
        startAnimation(false)
    }

    fun isSelect():Boolean{
        return mIsSelect
    }

    private fun startAnimation(isFromUser: Boolean){
        mIsAnimating=!mIsAnimating
        lateinit var va:ValueAnimator
        if(mIsSelect){
            va=ValueAnimator.ofFloat(1f,0f)
        }else{
            va=ValueAnimator.ofFloat(0f,1f)
        }

        va.duration=ANIMATION_DURATIONS

        va.addUpdateListener {
            mValue=it.animatedValue as Float
            invalidate()
        }

        va.addListener(object:AnimatorListener{
            override fun onAnimationStart(animation: Animator) {

            }

            override fun onAnimationEnd(animation: Animator) {
                mIsAnimating=!mIsAnimating
                mIsSelect=!mIsSelect
                invalidate()
                if(mOnSelectListener!=null)
                    mOnSelectListener!!.onSelect(mIsSelect,isFromUser)
            }

            override fun onAnimationCancel(animation: Animator) {

            }

            override fun onAnimationRepeat(animation: Animator) {

            }

        })

        /*va.addListener(object : AnimatorListener{
            override fun onAnimationStart(p0: Animator) {

            }

            override fun onAnimationEnd(p0: Animator) {
                mIsAnimating=!mIsAnimating
                mIsSelect=!mIsSelect
                invalidate()
            }

            override fun onAnimationCancel(p0: Animator) {

            }

            override fun onAnimationRepeat(p0: Animator) {

            }

        })*/

        va.interpolator = DecelerateInterpolator()
        va.start()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if(canvas==null)  return

        var deltaX=SB_WIDTH-SB_HEIGHT//switch slide total distance

        val selectPath=Path()
        val rdii= AlgorithmUtil.formatRadiiFloatArray(floatArrayOf(SB_HEIGHT/2,SB_HEIGHT/2,SB_HEIGHT/2,SB_HEIGHT/2))
        val selectRoundRect= RectF(0f,0f,SB_WIDTH  ,SB_HEIGHT)
        selectPath.addRoundRect(selectRoundRect,rdii,Path.Direction.CW)
        canvas.clipPath(selectPath)

        //close state bg
        val bgRect= RectF(0f,0f,SB_WIDTH,SB_HEIGHT)
        canvas.drawRoundRect(bgRect,SB_HEIGHT/2,SB_HEIGHT/2,mBgPaint)

        //open state bg
        val selectBgRect= RectF(0f,0f,SB_WIDTH*mValue  ,SB_HEIGHT)
        canvas.drawRoundRect(selectBgRect,SB_HEIGHT/2,SB_HEIGHT/2,mSelectBgPaint)

        //switch button
        canvas.drawCircle(SB_HEIGHT/2+deltaX*mValue,SB_HEIGHT/2,SB_HEIGHT/2-BUTTON_MARGIN*2,mBtnPaint)

    }

}